import {
  createMemo,
  createSignal,
  Index,
  mergeProps,
  Show,
  splitProps,
  type ComponentProps,
  type ParentComponent,
} from "solid-js";
import type { DropdownProps } from "./types";
import Slot from "@lib/Slot";
import BsButton from "@lib/Button";
import type { AsProp } from "@lib/helper";
import { Dynamic } from "solid-js/web";
import type { JSX } from "solid-js/jsx-runtime";

const DropdownBase: ParentComponent<DropdownProps> = (p) => {
  const [local, props] = splitProps(mergeProps({ display: "dynamic" }, p), [
    "slots",
    "children",
    "ref",
    "$ServerOnly",
    "classList",
    "items",
    "defaultProps",
    "listProps",
    "split",
    "noContainer",
    "centered",
    "direction",
    "alignment",
    "display"
  ]);

  const [btnRef, setBtnRef] = createSignal(false);
  const classList = createMemo(() => {
    return {
      ...local.classList,
      "btn-group": local.split,
      dropdown: !local.split,
      "dropdown-centered": local.centered,
      [`drop${local.direction}`]: local.direction !== undefined,
    };
  });

  const main = (
    <>
      {local.split && local.children}
      <Slot
        slot={local.slots?.default}
        context={{
          ref: setBtnRef,
          "data-bs-toggle": "dropdown",
          "data-bs-display": local.display,
          children: local.split ? (
            <span class="visually-hidden">Toggle Dropdown</span>
          ) : (
            local.children
          ),
          ...local.defaultProps,
          classList: {
            ...local.defaultProps?.classList,
            ["dropdown-toggle"]: true,
            ["dropdown-toggle-split"]: local.split,
          },
        }}
      >
        {BsButton}
      </Slot>
      <Slot
        slot={local.slots?.list}
        context={{
          class: "dropdown-menu",
          classList: { "dropdown-menu-end": local.alignment === "end" },
          children: local.items?.map((item) => <li>{item}</li>),
          ...local.listProps,
        }}
      >
        {(ctx) => <ul {...ctx}></ul>}
      </Slot>
    </>
  );

  return (
    <Show when={local.noContainer !== true} fallback={main}>
      <div ref={local.ref} classList={classList()} {...props}>
        {main}
      </div>
    </Show>
  );
};

const BsDropdownItem: ParentComponent<
  AsProp<any> & JSX.CustomAttributes<any> & ComponentProps<any>
> = (p) => {
  const [local, props] = splitProps(p, ["as", "$ServerOnly", "classList"]);
  const classList = createMemo(() => {
    return {
      "dropdown-item": true,
      ...local.classList,
    };
  });

  return (
    <Dynamic component={local.as} classList={classList()} {...props}></Dynamic>
  );
};

const BsDropdownDivider = () => {
  return <hr class="dropdown-divider" />;
};

const BsDropdownHeader: ParentComponent<any> = (p) => {
  return <h6 class="dropdown-header">{p.children}</h6>;
};

type CompoundedComponent = typeof DropdownBase & {
  Item: typeof BsDropdownItem;
  Divider: typeof BsDropdownDivider;
  Header: typeof BsDropdownHeader;
};

const BsDropdown = DropdownBase as CompoundedComponent;
BsDropdown.Item = BsDropdownItem;
BsDropdown.Divider = BsDropdownDivider;
BsDropdown.Header = BsDropdownHeader;

export default BsDropdown;
